#include "ioeventloop.h"
#include "ioallocator.h"

#if (TARGET_OS == OS_WINDOWS)
	#include <event2/iocp-internal.h>
#endif



uvNameSpaceBegin
//////////////////////////////////////////////////////////////////////////////////
static int init_threads() {

#if (TARGET_OS == OS_WINDOWS)
	return evthread_use_windows_threads();
#elif (TARGET_OS == OS_POSIX)
	return evthread_use_pthreads();
#elif (TARGET_OS == OS_MAC)
	return evthread_use_pthreads();
#endif
	return 0;
}

static int init_iocp(io_event_loop* eventloop) {

#if (TARGET_OS == OS_WINDOWS)
	struct event_iocp_port *port = NULL;
	event_base_start_iocp_(eventloop->loop, 1);
	port = event_base_get_iocp_(eventloop->loop);
#endif
	return 1;
}

static void OnTime(int sock, short event, void *arg)
{
	retret(arg);
	io_event_loop* eventloop = (io_event_loop*)(arg);
	if (eventloop->evtime != NULL) {
		event_del(eventloop->evtime);
		event_free(eventloop->evtime);
		eventloop->evtime = NULL;
		eventloop->cb(1, eventloop->data);
	}
}

static void do_Notify(io_event_loop* eventloop) {

	eventloop->evtime = evtimer_new(eventloop->loop, OnTime, eventloop); //event_new(eventloop->loop, -1,0, onTime, eventloop);
	eventloop->tv.tv_sec = 0;
	eventloop->tv.tv_usec = 1;
	event_add(eventloop->evtime, &eventloop->tv);
}
int create_ioeventloop(io_event_loop* eventloop, event_thread_cb cb, void*	data) {

	init_threads();
	eventloop->loop = event_base_new();
	eventloop->cb = cb;
	eventloop->data = data;
	eventloop->size = 0;
	init_iocp(eventloop);

	return 1;
}
int destory_ioeventloop(io_event_loop* eventloop) {

	ptrnull_value(eventloop, IO_VALUE_ERROR);
	ptrnull_value(eventloop->loop, IO_VALUE_ERROR);
	event_base_loopexit(eventloop->loop, NULL);
	return 1;
}
int run_ioeventloop(io_event_loop* eventloop) {

	ptrnull_value(eventloop, IO_VALUE_ERROR);

	do_Notify(eventloop);
	iosprintf("run_ioeventloop")
	event_base_loop(eventloop->loop, EVLOOP_NO_EXIT_ON_EMPTY);
	eventloop->cb(0, eventloop->data);
	event_base_free(eventloop->loop);
	iosprintf("run_ioeventloop free")

	eventloop->loop = NULL;
	eventloop->size = 0;
	return 1;
}


//////////////////////////////////////////////////////////////////////////////////
uvNameSpaceEnd